package com.zmyuan.demo.netty.thrift.client;

import com.zmyuan.demo.netty.thrift.Content;
import com.zmyuan.demo.netty.thrift.Msg;
import com.zmyuan.demo.netty.thrift.ThriftRequest;
import com.zmyuan.demo.netty.thrift.codec.ThriftClientEncoder;
import com.zmyuan.demo.netty.thrift.common.Constants;
import com.zmyuan.demo.netty.thrift.utils.ThriftUtils;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.http.*;
import io.netty.util.AttributeKey;

import java.net.URI;

/**
 * Created by zdb on 2017/2/14.
 */
public class ThriftClientTest {

    public static <T>T startClient(Object req, Class<T> tClass) {
        int port = 8999;
        String host = "localhost";
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            Bootstrap b = new Bootstrap(); // (1)
            b.group(workerGroup); // (2)
            b.channel(NioSocketChannel.class); // (3)
            b.option(ChannelOption.SO_KEEPALIVE, true); // (4)
            b.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(new ThriftClientEncoder())
                            .addLast(new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()[0]))
                            .addLast(new ThriftClientHandler());
                }
            });

            // Start the client.
            ChannelFuture f = b.connect(host, port).sync(); // (5)

//            ThriftRequest req = new ThriftRequest();
//            req.setCommand("saveContent");
//            Content content = new Content();
//            content.setId(1);
//            content.setPhone("18812345678").setPrice(11);
//
//            req.setRequestParam(ThriftUtils.convertThriftObjToBytes(content));

            f.channel().writeAndFlush(req);

            // Wait until the connection is closed.
            f.channel().closeFuture().sync();

            ByteBuf buf = (ByteBuf)f.channel().attr(AttributeKey.valueOf(Constants.ATTRIBUTE_KEY)).get();
            byte[] dst = null;
            if(buf.hasArray()) {
                dst = buf.array();
            } else {
                dst = new byte[buf.readableBytes()];
                buf.readBytes(dst);
            }
            T obj = ThriftUtils.convertBytesToObject(dst, tClass);
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            workerGroup.shutdownGracefully();
        }
        return null;
    }

    public static void main(String[] args) throws Exception {

        ThriftRequest req = new ThriftRequest();
        req.setCommand("saveContent");
        Content content = new Content();
        content.setId(1);
        content.setPhone("18812345678").setPrice(11);

        req.setRequestParam(ThriftUtils.convertThriftObjToBytes(content));

        Content c = startClient(req, Content.class);
        System.out.println(c.getPhone());

    }
}
